#include "hal_data.h"

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER


/* 用户头文件包含 */
#include "led/bsp_led.h"
#include "debug_uart/bsp_debug_uart.h"
#include "canfd/bsp_canfd0.h"
#include "canfd/bsp_canfd1.h"


/* 外部变量和函数声明 */
extern volatile bool canfd0_rx_complete_flag;
extern can_frame_t canfd0_tx_frame;
extern can_frame_t canfd0_rx_frame;

extern volatile bool canfd1_rx_complete_flag;
extern can_frame_t canfd1_rx_frame;
extern can_frame_t canfd1_tx_frame;

extern volatile bool canfd0_senddata_enable;
extern volatile bool canfd1_senddata_enable;


/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */

    LED_Init();         // LED 初始化
    Debug_UART4_Init(); // SCI4 UART 调试串口初始化

    /* CAN-FD 模块初始化 */
    CANFD0_Init();
    CANFD1_Init();

    printf("这是一个 CAN FD 通讯例程\r\n");
    printf("打开串口助手发送以下指令，对 CAN-FD 进行相应的操作\r\n");
    printf("\t指令   ------  操作\r\n");
    printf("\t 0   ------  CAN-FD0 发送数据帧\r\n");
    printf("\t 1   ------  CAN-FD1 发送数据帧\r\n");
    printf("\t=======================================\r\n\r\n");


    while(1)
    {
        if (true == canfd0_senddata_enable)
        {
            canfd0_senddata_enable = false; //清零标志位
            
            /* 测试从 CANFD0 发送到 CANFD1 */
            CANFD0_Operation();
            
            printf("等待 CANFD1 接收完成中断\r\n");
            while (false == canfd1_rx_complete_flag);
            canfd1_rx_complete_flag = false;

            printf("CANFD0 > CANFD1 开始验证数据\r\n");
            for( uint16_t j = 0; j < canfd0_tx_frame.data_length_code; j++)
            {
                if (canfd0_tx_frame.data[j] != canfd1_rx_frame.data[j])
                {
                    printf("CANFD0发送数据与CANFD1接收数据不一致\r\n");
                }
            }
            printf("CANFD0 > CANFD1 测试完成\r\n\r\n");
        }
        
        if (true == canfd1_senddata_enable)
        {
            canfd1_senddata_enable = false; //清零标志位
            
            /* 测试从 CANFD1 发送到 CANFD0 */
            CANFD1_Operation();
            
            printf("等待 CANFD0 接收完成中断\r\n");
            while (false == canfd0_rx_complete_flag);
            canfd0_rx_complete_flag = false;
            
            printf("CANFD1 > CANFD0 开始验证数据\r\n");
            for( uint16_t j = 0; j < canfd1_tx_frame.data_length_code; j++)
            {
                if (canfd1_tx_frame.data[j] != canfd0_rx_frame.data[j])
                {
                    printf("CANFD1发送数据与CANFD0接收数据不一致\r\n");
                }
            }
            printf("CANFD1 > CANFD0 测试完成\r\n\r\n");
        }
    }


#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
    }
}

#if BSP_TZ_SECURE_BUILD

BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
#endif
